﻿namespace TestTool.GUI
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Threading;
    using System.Windows.Forms;
    using System.Xml.Serialization;
    using TestTool.GUI.Controllers;
    using TestTool.GUI.Data;
    using TestTool.GUI.Utils;
    using TestTool.Tests.Definitions.Data;
    using TestTool.Tests.Engine;

    internal class SilentProcessingController
    {
        private TestController _controller;
        private string _errorLog;
        private Dictionary<string, string> _options;
        private SilentTestView _view;

        public SilentProcessingController(CompactProcessingForm view)
        {
            this._view = new SilentTestView(view);
            view.Closing += new CancelEventHandler(this.view_Closing);
        }

        private void controller_ConformanceInitializationCompleted(ConformanceInitializationData data)
        {
            this._view.DefineTestCount(data.TestsSelected.Count);
        }

        private TestLogFull GetTestLog(TestSuiteParameters testSuiteParameters, SerializableTestingParameters parameters, TestController controller)
        {
            controller.UpdateTestLog();
            TestLogFull full = new TestLogFull();
            TestLog testLog = ContextController.GetTestLog();
            full.TestResults = testLog.TestResults;
            full.Features = testLog.Features;
            full.InitializationData = testLog.InitializationData;
            full.FeaturesDefinitionLog = testLog.FeaturesDefinitionLog;
            full.DeviceInformation = controller.DeviceInformation;
            if (testLog.TestExecutionTime != DateTime.MinValue)
            {
                full.TestExecutionTime = testLog.TestExecutionTime;
            }
            else
            {
                full.TestExecutionTime = DateTime.Now;
            }
            full.Application = new ApplicationInfo();
            full.DeviceEnvironment = new DeviceEnvironment();
            full.DeviceEnvironment.Credentials = new Credentials();
            full.DeviceEnvironment.Credentials.UserName = testSuiteParameters.UserName;
            full.DeviceEnvironment.TestSettings = new TestSettings();
            full.DeviceEnvironment.TestSettings.OperationDelay = testSuiteParameters.OperationDelay;
            full.DeviceEnvironment.TestSettings.RecoveryDelay = testSuiteParameters.RecoveryDelay;
            if (parameters.Device != null)
            {
                full.ProductName = parameters.Device.Model;
            }
            if (parameters.SessionInfo != null)
            {
                full.TesterInfo = parameters.SessionInfo.TesterInfo;
                full.OtherInformation = parameters.SessionInfo.OtherInformation;
                full.MemberInfo = parameters.SessionInfo.MemberInfo;
            }
            return full;
        }

        private bool LoadOptions(string[] args)
        {
            this._options = new Dictionary<string, string>();
            for (int i = 0; i < args.Length; i++)
            {
                if (CommandLineArgs.OPTIONS.Contains<string>(args[i]))
                {
                    if (i < (args.Length - 1))
                    {
                        this._options.Add(args[i], args[i + 1]);
                    }
                    i++;
                }
            }
            return true;
        }

        private SerializableTestingParameters LoadParameters()
        {
            SerializableTestingParameters parameters = null;
            if (this._options.ContainsKey("-p"))
            {
                string path = this._options["-p"];
                if (!File.Exists(path))
                {
                    this.SaveErrorLog(string.Format("File not found: {0}", path));
                    return null;
                }
                XmlSerializer serializer = new XmlSerializer(typeof(SerializableTestingParameters));
                FileStream stream = null;
                try
                {
                    stream = new FileStream(path, FileMode.Open);
                    parameters = (SerializableTestingParameters) serializer.Deserialize(stream);
                }
                catch (Exception exception)
                {
                    this.SaveErrorLog(string.Format("Parameters loading failed: {0}", exception.Message));
                    return null;
                }
                finally
                {
                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
            }
            return parameters;
        }

        public void Run(string[] args)
        {
            if (args.Contains<string>("-p"))
            {
                AutoResetEvent completed;
                bool completedOk;
                this.LoadOptions(args);
                SerializableTestingParameters parameters = this.LoadParameters();
                if (parameters != null)
                {
                    TestController controller = new TestController(this._view);
                    this._controller = controller;
                    completed = new AutoResetEvent(false);
                    completedOk = true;
                    controller.TestSuiteCompleted += delegate (bool normally) {
                        completedOk = normally;
                        completed.Set();
                    };
                    controller.ConformanceInitializationCompleted += new Action<ConformanceInitializationData>(this.controller_ConformanceInitializationCompleted);
                    controller.LoadTests();
                    TestSuiteParameters testSuiteParameters = parameters.GetTestSuiteParameters();
                    testSuiteParameters.AdvancedParameters = new Dictionary<string, object>();
                    if (parameters.Advanced != null)
                    {
                        foreach (object obj2 in AdvancedParametersUtils.Deserialize(parameters.Advanced, controller.AdvancedSettingsTypes))
                        {
                            testSuiteParameters.AdvancedParameters.Add(obj2.GetType().GUID.ToString(), obj2);
                        }
                    }
                    controller.RunConformanceSilent(testSuiteParameters);
                    completed.WaitOne();
                    if (completedOk)
                    {
                        try
                        {
                            Output output = parameters.Output;
                            string directory = string.Empty;
                            if (output != null)
                            {
                                directory = output.Directory;
                            }
                            if (string.IsNullOrEmpty(directory))
                            {
                                directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "ONVIF Device Test Tool");
                            }
                            string path = directory;
                            if (!Directory.Exists(directory))
                            {
                                Directory.CreateDirectory(directory);
                            }
                            if ((output != null) && output.CreateNestedFolder)
                            {
                                string str3 = DateTime.Now.ToString("yyyy-MM-dd hh-mm");
                                path = Path.Combine(directory, str3);
                                Directory.CreateDirectory(path);
                            }
                            TestLogFull log = this.GetTestLog(testSuiteParameters, parameters, controller);
                            string report = null;
                            if (output != null)
                            {
                                report = output.Report;
                            }
                            if (string.IsNullOrEmpty(report) && (log.DeviceInformation != null))
                            {
                                report = string.Format("{0} - report.pdf", log.ProductName);
                            }
                            if (string.IsNullOrEmpty(report))
                            {
                                report = "report.pdf";
                            }
                            report = Path.Combine(path, report);
                            new PdfReportGenerator().CreateReport(report, log);
                            string declarationOfConformance = null;
                            if (output != null)
                            {
                                declarationOfConformance = output.DeclarationOfConformance;
                            }
                            if (string.IsNullOrEmpty(declarationOfConformance) && (log.DeviceInformation != null))
                            {
                                declarationOfConformance = string.Format("{0} - DoC.pdf", log.ProductName);
                            }
                            if (string.IsNullOrEmpty(declarationOfConformance))
                            {
                                declarationOfConformance = "DoC.pdf";
                            }
                            declarationOfConformance = Path.Combine(path, declarationOfConformance);
                            new DoCGenerator().CreateReport(declarationOfConformance, log);
                            if (output != null)
                            {
                                if (!string.IsNullOrEmpty(output.TestLog))
                                {
                                    string fileName = Path.Combine(path, output.TestLog);
                                    List<TestResult> results = new List<TestResult>();
                                    foreach (TestInfo info in controller.TestInfos)
                                    {
                                        TestResult testResult = controller.GetTestResult(info);
                                        if (testResult != null)
                                        {
                                            results.Add(testResult);
                                        }
                                    }
                                    controller.Save(fileName, results);
                                }
                                if (!string.IsNullOrEmpty(output.FeatureDefinitionLog))
                                {
                                    string str7 = Path.Combine(path, output.FeatureDefinitionLog);
                                    TestResult result2 = new TestResult {
                                        Log = this._controller.GetFeaturesDefinitionLog().Log,
                                        PlainTextLog = this._controller.GetFeaturesDefinitionLog().PlainTextLog
                                    };
                                    controller.Save(str7, result2);
                                }
                            }
                        }
                        catch (Exception exception)
                        {
                            this.SaveErrorLog(string.Format("Failed to create documents: {0}", exception.Message));
                        }
                    }
                }
            }
        }

        private void SaveErrorLog(string entry)
        {
            if (string.IsNullOrEmpty(this._errorLog))
            {
                string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"ONVIF\ONVIF Device Test Tool");
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                string str3 = string.Format("ErrorLog {0}.txt", DateTime.Now.ToString("yyyy-MM-dd hh-mm"));
                this._errorLog = Path.Combine(path, str3);
            }
            StreamWriter writer = File.AppendText(this._errorLog);
            writer.WriteLine(entry);
            writer.Close();
        }

        private void view_Closing(object sender, CancelEventArgs e)
        {
            if ((this._controller != null) && this._controller.Running)
            {
                e.Cancel = true;
                MessageBox.Show("Testing is running, unable to close the form.");
            }
        }
    }
}

